import axios from "axios";
import { Notification, MessageBox, Message } from "element-ui";
import store from "@/store";
import { getAccessToken, getRefreshToken } from "@/utils/auth";
import errorCode from "@/utils/errorCode";

import { getAuthorizeUrl } from "@/api/login"; //认证url
// || import.meta.env.VITE_APP_BASE_API
axios.defaults.headers["Content-Type"] = "application/json;charset=utf-8";
// 创建axios实例
const service = axios.create({
  // axios中请求配置有baseURL选项，表示请求URL公共部分
  baseURL: process.env.VUE_APP_BASE_API,
  // 超时
  timeout: 10000,
});
// request拦截器
service.interceptors.request.use(
  (config) => {
    config.headers["cache-control"] = "no-cache";
    config.headers["Pragma"] = "no-cache";
    // 是否需要设置 token
    const isToken = (config.headers || {}).isToken === false;
    if (getAccessToken() && !isToken) {
      config.headers["Authorization"] = "Bearer " + getAccessToken(); // 让每个请求携带自定义token 请根据实际情况自行修改
    }

    // get请求映射params参数
    if (config.method === "get" && config.params) {
      let url = config.url + "?";
      for (const propName of Object.keys(config.params)) {
        let value = config.params[propName];

        if (!value && typeof value != "boolean" && typeof value != "number") {
          continue;
        }
        if (value && typeof value == "string") {
          value = value.trim();
        }

        var part = encodeURIComponent(propName) + "=";
        if (value !== null && typeof value !== "undefined") {
          if (typeof value === "object") {
            for (const key of Object.keys(value)) {
              let params = propName + "[" + key + "]";
              var subPart = encodeURIComponent(params) + "=";
              url += subPart + encodeURIComponent(value[key]) + "&";
            }
          } else {
            url += part + encodeURIComponent(value) + "&";
          }
        }
      }
      url = url.slice(0, -1);
      config.params = {};
      config.url = url;
    }
    return config;
  },
  (error) => {
    console.log(error);
    Promise.reject(error);
  }
);

// 是否正在刷新的标记
let isRefreshing = false;
// 重试队列，每一项将是一个待执行的函数形式
let requests = [];

let redirectConfirmVisible = false;
// 响应拦截器
service.interceptors.response.use(
  (res) => {
    if (res.config.responseType == "blob") {
      //文件下载
      if (res.headers["content-disposition"]) {
        return res;
      }
      if (res.headers["content-type"].includes("application/json")) {
        let reader = new FileReader();
        reader.onload = (e) => {
          console.log(e.target.readyState);
          if (e.target.readyState === 2) {
            let res = {};
            res = JSON.parse(e.target.result);
            console.info("back:: ", res);
            Message({
              message: res.msg,
              type: "error",
            });
          }
        };
        reader.readAsText(res.data);
      }
    } else {
      // 未设置状态码则默认成功状态
      const code = res.data.code || 200;
      // 获取错误信息
      const msg = res.data.msg || errorCode[code] || errorCode["default"];
      if (code === 500) {
        Message({
          message: msg,
          type: "error",
        });
        return Promise.reject(new Error(msg));
      } else if (code !== 200) {
        Notification.error({
          title: msg,
        });
        return Promise.reject("error");
      } else {
        if (!res.data.success && !res.config.url.includes("refreshToken")) {
          Message({
            message: res.data.msg,
            type: "error",
          });
        }
        return res.data;
      }
    }
  },
  (error) => {
    if (error.response) {
      if (error.response.status === 401) {
        const { config } = error.response;
        if (!isRefreshing) {
          isRefreshing = true;
          return store
            .dispatch("RefreshToken")
            .then((res) => {
              config.headers["Authorization"] = "Bearer " + getAccessToken();
              // 已经刷新了token，将所有队列中的请求进行重试
              requests.forEach((cb) => cb());
              // 重试完了别忘了清空这个队列（
              requests = [];
              return service(config);
            })
            .catch((res) => {
              if (!redirectConfirmVisible) {
                redirectConfirmVisible = true;
                MessageBox.confirm(
                  "登录状态已过期，您可以继续留在该页面，或者重新登录",
                  "系统提示",
                  {
                    confirmButtonText: "重新登录",
                    cancelButtonText: "取消",
                    type: "warning",
                  }
                )
                  .then(() => {
                    store.dispatch("LogOut", window.location.href).then(() => {
                      // location.href = "/index";
                      getAuthorizeUrl().then((res) => {
                        if (res.success) {
                          const url = res.data;
                          window.location = url;
                        }
                      });
                    });
                  })
                  .catch()
                  .finally(() => {
                    redirectConfirmVisible = false;
                  });
              }
            })
            .finally(() => {
              isRefreshing = false;
            });
        } else {
          // 正在刷新token，返回一个未执行resolve的promise
          return new Promise((resolve) => {
            // 将resolve放进队列，用一个函数形式来保存，等token刷新后直接执行
            requests.push(() => {
              resolve(service(config));
            });
          });
        }
      } else if (error.response.status === 403) {
        Message({
          message: errorCode["403"],
          type: "error",
          duration: 5 * 1000,
        });
        return Promise.reject(error);
      }
    }

    let { message } = error;
    console.log(error);
    if (message == "Network Error") {
      message = "无法连接服务器";
    } else if (message.includes("timeout")) {
      message = "系统接口请求超时";
    } else if (message.includes("Request failed with status code")) {
      message = "系统接口" + message.substr(message.length - 3) + "异常";
    }
    Message({
      message: message,
      type: "error",
      duration: 5 * 1000,
    });
    return Promise.reject(error);
  }
);

export default service;
